function result_image=pco_camera_getone(glvar,mainhandle)
%
%   pco_rec2file_swtrig(imacount)
%
%	* Input parameters :
%                  imacount
%	* Output parameters :
%
%records and saves to disk 'imacount' images
%the actual setup of the camera is used, with the fiollowing modifications
%storage mode is set to STORAGE_MODE_FIFO
%recorder submode is set to RECORDER_SUBMODE_RINGBUFFER
%trigger mode is set to SOFTWARE_TRIGGER
%
%function workflow
%parameters are checked
%camera parameters are set
%camera is armed
%camera is started
%memory for one image is allocated
%
%the function does the following loop until imacount  images are done
%
%control external components
%send force trigger, one image is done
%wait until image is in camera memory
%get image from camera
%save image to disk
%
%free allocated memory
%stop camera

for I=1:length(glvar)
out_ptr=glvar(I).out_ptr;

%test camera recording state and stop camera, if camera is recording
act_recstate = uint16(0);
[errorCode,out_ptr,act_recstate] = calllib('PCO_CAM_SDK', 'PCO_GetRecordingState', out_ptr,act_recstate);
if(errorCode)
    disp(['PCO_GetRecordingState failed with error ',num2str(errorCode,'%X')]);
end

if(act_recstate~=0)
    [errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_SetRecordingState', out_ptr, 0);
    if(errorCode)
        disp(['PCO_SetRecordingState failed with error ',num2str(errorCode,'%X')]);
    end
end

%set TRIGGER_MODE_SOFTWARETRIGGER
[errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_SetTriggerMode', out_ptr,1);
if(errorCode)
    disp(['PCO_SetTriggerMode failed with error ',num2str(errorCode,'%X')]);
end

[errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_ArmCamera', out_ptr);
if(errorCode)
    disp(['PCO_ArmCamera failed with error ',num2str(errorCode,'%X')]);
end

[errorCode] = calllib('PCO_CAM_SDK', 'PCO_SetRecordingState', out_ptr, 1);
if(errorCode)
    disp(['PCO_SetRecordingState failed with error ',num2str(errorCode,'%X')]);
end

%declare some variables and get some information from camera
dwValidImageCnt=uint32(0);
dwMaxImageCnt=uint32(0);
wtrigdone=uint16(0);
dwSec=uint32(0);
dwNanoSec=uint32(0);
bitpix=uint16(14);

%get time in ms, which is used for one image
[errorCode,out_ptr,dwSec,dwNanoSec] = calllib('PCO_CAM_SDK', 'PCO_GetCOCRuntime', out_ptr,dwSec,dwNanoSec);
if(errorCode)
    disp(['PCO_GetCOCRuntime failed with error ',num2str(errorCode,'%X')]);
end

waittime_s = double(dwNanoSec);
waittime_s = waittime_s / 1000000000;
waittime_s = waittime_s + double(dwSec);

act_segment = uint16(0);
[errorCode,out_ptr,act_segment] = calllib('PCO_CAM_SDK', 'PCO_GetActiveRamSegment', out_ptr,act_segment);
if(errorCode)
    disp(['PCO_GetActiveRamSegment failed with error ',num2str(errorCode,'%08X')]);
    return;
end

% disp(['Active Segment ',int2str(act_segment)]);
% [errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_ClearRamSegment', out_ptr);
% if(errorCode)
%     disp(['PCO_ClearRamSegment failed with error ',num2str(errorCode,'%X')]);
% end
% act_align = uint16(0);
% [errorCode,out_ptr,act_align] = calllib('PCO_CAM_SDK', 'PCO_GetBitAlignment', out_ptr,act_align);
% if(errorCode)
%     disp(['PCO_GetBitAlignment failed with error ',num2str(errorCode,'%08X')]);
%     return;
% end
% disp(['Actual Alignment ',int2str(act_align)]);

ml_strSegment.wSize=uint16(108);
strSegment=libstruct('PCO_Segment',ml_strSegment);
[errorCode,out_ptr,strSegment] = calllib('PCO_CAM_SDK', 'PCO_GetSegmentStruct', out_ptr,act_segment,strSegment);
if(errorCode)
    disp(['PCO_GetSegmentStruct failed with error ',num2str(errorCode,'%08X')]);
    return;
end
disp(['Segmentstruct XRes ',int2str(strSegment.wXRes),'  YRes ',int2str(strSegment.wYRes)]);

% [errorCode,out_ptr]  = calllib('PCO_CAM_SDK', 'PCO_CamLinkSetImageParameters', out_ptr,strSegment.wXRes,strSegment.wYRes);
% if(errorCode)
%     disp(['PCO_CamLinkSetImageParameters failed with error ',num2str(errorCode,'%08X')]);
%     return;
% end

%get the memory for the image
%need special code for firewire interface

imas=uint32(fix((double(bitpix)+7)/8));
imas= imas*uint32(strSegment.wYRes)* uint32(strSegment.wXRes);
imasize=imas;


i=floor(double(imas)/4096);
i=i+1;
i=i*4096;
imasize=i;
i=i-double(imas);
xs=uint32(fix((double(bitpix)+7)/8));
xs=xs*strSegment.wXRes;
i=floor(i/double(xs));
i=i+1;
lineadd=i;
disp(['imasize is: ',int2str(imas),' aligned: ',int2str(imasize)]);
disp([int2str(lineadd),' additional lines have been allocated ']);


image_stack=ones(strSegment.wXRes,strSegment.wYRes+lineadd,'uint16');

sBufNr=int16(-1);
im_ptr = libpointer('uint16Ptr',image_stack);
ev_ptr = libpointer('voidPtr');

[errorCode,out_ptr,sBufNr,image_stack,ev_ptr]  = calllib('PCO_CAM_SDK','PCO_AllocateBuffer', out_ptr,sBufNr,imasize,im_ptr,ev_ptr);
if(errorCode)
    disp(['PCO_AllocateBuffer failed with error ',num2str(errorCode,'%08X')]);
    return;
end

[errorCode,out_ptr,wtrigdone] = calllib('PCO_CAM_SDK', 'PCO_ForceTrigger', out_ptr,wtrigdone);
if(errorCode)
    disp(['PCO_ForceTrigger failed with error ',num2str(errorCode,'%X')]);
end

dwValidImageCnt=0;
a=0;

[errorCode,out_ptr,dwValidImageCnt,dwMaxImageCnt]  = calllib('PCO_CAM_SDK', 'PCO_GetNumberOfImagesInSegment', out_ptr,act_segment,dwValidImageCnt,dwMaxImageCnt);
if(errorCode)
    disp(['PCO_GetNumberOfImagesInSegment failed with error ',num2str(errorCode,'%X')]);
end
disp(['segment ',int2str(act_segment),':  valid images: ',int2str(dwValidImageCnt),' max images ',int2str(dwMaxImageCnt)]);
% pause(waittime_s);
a=a+1;
if(a>10)
    disp('timeout in waiting for images');
    errorCode=1;
end

if(errorCode==0)
    [errorCode,out_ptr]  = calllib('PCO_CAM_SDK','PCO_GetImageEx',out_ptr,act_segment,0,0,sBufNr,strSegment.wXRes,strSegment.wYRes,bitpix);
    if(errorCode)
        disp(['PCO_GetImageEx failed with error ',num2str(errorCode,'%08X')]);
    else
        disp(['PCO_GetImageEx image ' int2str(1) ' done']);
    end
end

if(errorCode==0)
    [errorCode,out_ptr,image_stack]  = calllib('PCO_CAM_SDK','PCO_GetBuffer',out_ptr,sBufNr,im_ptr,ev_ptr);
    if(errorCode)
        disp(['PCO_GetBuffer failed with error ',num2str(errorCode,'%08X')]);
    end
end
act_ysize=strSegment.wYRes;
if mainhandle.setcamdata.doubleimage==1
    result_image=image_stack(:,1:act_ysize)';
else
    result_image(:,:,1)=image_stack(:,1:act_ysize/2)';
    result_image(:,:,2)=image_stack(:,act_ysize/2+1:act_ysize)';
end


errorCode  = calllib('PCO_CAM_SDK','PCO_FreeBuffer',out_ptr,sBufNr);
if(errorCode)
    disp(['PCO_FreeBuffer failed with error ',num2str(errorCode,'%08X')]);
end

clear image_stack;

[errorCode] = calllib('PCO_CAM_SDK', 'PCO_SetRecordingState', out_ptr, 0);
if(errorCode)
    disp(['PCO_SetRecordingState failed with error ',num2str(errorCode,'%X')]);
end
end
end


